package com.brand.data.service.yqdz;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;

import com.brand.data.model.DataCrawThread;
import com.brand.data.model.RequestParam;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.brand.data.model.ResultData;
import com.brand.data.service.SpiderService;

import lombok.extern.slf4j.Slf4j;

/**
 * @author scl.BlueOcean
 * @version 1.0
 * @date 2018年02月26 14:37
 * @description 一汽大众
 */
@RestController
@RequestMapping("yqdz")
@Slf4j
public class YqdzSpider implements SpiderService{
	private static final String BRAND_CODE = "yqdz";
	private static final String BRAND_NAME = "一汽大众";
	@Override
	public String getBrandCode() {
		return BRAND_CODE;
	}
	@Override
	public String getBrandName() {
		return BRAND_NAME;
	}
    @Autowired
    @Qualifier("yqdzCrawService")
    private YqdzCrawService dataCrawlService;
    @Autowired
	private ThreadPoolTaskExecutor pool;
    @RequestMapping("query")
    public Object query(String vin,String engine) {
        log.info("查询vin：{}",vin);
        List<ResultData> results = getResults(vin,0);
        queryDetail(results, vin);
        //判断查询结果详情数据是否都为空异常
        judgeEmpty(results,vin);
        return results;
    }
	private List<ResultData> getResults(String vin,int time) {
		Object body = dataCrawlService.queryList(vin);
		List<ResultData> results = parseListResultAndGetDetailParams(body);
		if(results==null || results.isEmpty()){
			if (time < 3 && !body.toString().contains("未找到合适的数据")) {
				try {
					Thread.sleep(30*1000);
				} catch (InterruptedException e) {}
				return getResults(vin, ++time);
			}
		}
		return results;
	}

	/**
	 * @param results
	 */
	private void judgeEmpty(List<ResultData> results,String vin) {
		if (results != null && !results.isEmpty()) {
			boolean flag = true;
			for (ResultData resultData : results) {
				if (!resultData.getMaterials().isEmpty()|| !resultData.getDetails().isEmpty()) {
					flag = false;
					break;
				}
			}
			if (flag) {
				throw new RuntimeException("vin->"+vin+"详情数据都为空异常");
			}
		}
	}
	private List<ResultData> parseListResultAndGetDetailParams(Object body) {
		List<ResultData> results = new ArrayList<>();
		if (body != null && !body.toString().contains("未找到合适的数据")){
			Document document = Jsoup.parse((String) body);
            Elements trs = document.select("tr[id^='row']");
            if (trs!= null && !trs.isEmpty()){
                for (Element tr : trs) {
                    RequestParam detailParam = getDetailParam(document,tr.child(1));
                    ResultData result = new ResultData();
                    result.setType(tr.child(1).text());
                    result.setLastTime(tr.child(4).text());
                    result.setMileage(tr.child(5).text());
                    result.setDetailParam(detailParam);
                    results.add(result);
                }
            }
        }
		if (results.isEmpty()&&body!=null) {
			log.info("结果集为空，查询结果为==>{}",body.toString());
		}

		return results;
	}

    private RequestParam getDetailParam(Document document, Element tr) {
        RequestParam param = RequestParam.newParam();
        Elements inputs = document.select("input[name]:not([name^=condition])");
        for (Element input : inputs) {
            param.addParam(new String(input.attr("name")), input.val());
        }

        String onclick = tr.attr("onclick");
        onclick = onclick.substring(onclick.indexOf("(") + 1, onclick.indexOf(")")).replaceAll("'", "");
        String[] vals = onclick.split(",");
        param.addParam("condition1", vals[0])
                .addParam("condition2", vals[1])
                .addParam("condition3", vals[2])
                .addParam("condition4", vals[3]);
        return param;
    }

    private void queryDetail(List<ResultData> results, String vin) {
    	
		if ((results != null) && (!results.isEmpty())) {
            CountDownLatch latch = new CountDownLatch(results.size());
			for (ResultData result : results) {
				pool.submit(new DataCrawThread(latch) {
					@Override
					public void run() {
						try {
                            queryDetial(vin, result,0);
						}finally {
							latch.countDown();
						}
					}
					
				});
			}

			try {
				latch.await();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
    private void queryDetial(String vin, ResultData result,int times) {
		try {
			RequestParam detailParam = result.getDetailParam();
			Object detail = dataCrawlService.queryDetail(result.getDetailParam());
			try {
				parseDetailBody(detail, result, vin);
			} catch (Exception e) {
				log.error("vin->{}解析详情出现异常,详情参数:{},详情内容是：{}",vin,detailParam,detail);
			}
		} catch (Exception e) {
			if (times < 3) {
				try {
					Thread.sleep(2000);
				} catch (InterruptedException e1) {}
    			queryDetial(vin, result, ++times);
			}
			throw e;
		}
	}
	/**
	 * @param detail
	 * @param result
	 * @param vin
     *
	 */
	private void parseDetailBody(Object detail, ResultData result, String vin) {
		result.setVin(vin);
		result.setDetailParam(null);
		if (detail!=null) {
		    Document document = Jsoup.parse((String) detail);
            Elements tables = document.getElementsByTag("table");
            if (tables != null && !tables.isEmpty()){
                parseDetail(result, tables.get(3));
                parseMaterial(result, tables.get(4));
            }
		}
		
	}
	/**
     * @param result
     * @param table
     */
	private void parseMaterial(ResultData result, Element table) {
		try {
            Elements trs = table.select("tr:gt(1)");
            if (trs != null && !trs.isEmpty()){
                for (Element tr : trs) {
                	if (tr.text().contains("没有找到查询记录")) {
						break;
					}
                    String content =String.format("%s;%s",tr.child(1).text(),tr.child(2).text());
                    String type = tr.child(3).text();
                    result.getMaterials().add(result.new Material(content,type));
                }
            }
		} catch (Exception e) {
			log.error("vin->{}解析材料详情时出错,错误结果==>{}",result.getVin(),table.toString());
			log.error("vin->{}解析材料详情时出错,",e);
		}
	}

	/**
     * @param result
     * @param table
     */
	private void parseDetail(ResultData result, Element table) {
		try {
            Elements trs = table.select("tr:gt(1)");
            if (trs != null && !trs.isEmpty()){
                for (Element tr : trs) {
                	if (tr.text().contains("没有找到查询记录")) {
						break;
					}
                    String content =String.format("%s;%s",tr.child(1).text(),tr.child(2).text());
                    String type = tr.child(3).text();
                    result.getDetails().add(result.new Detail(content,type));
                }
            }
        } catch (Exception e) {
        	log.error("vin->{}解析项目详情时出错,错误结果==>{}",result.getVin(),table.toString());
			log.error("vin->{}解析项目详情时出错,",e);
		}
	}
	@GetMapping("swich")
	public boolean swichTask(){
		YqdzTaskService.flag = !YqdzTaskService.flag;
		return YqdzTaskService.flag;
	}
}
